# gui/cpu_scheduler_gui.py
import sys
import os
import subprocess
import configparser
import tempfile
import glob
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, 
                             QHBoxLayout, QLabel, QSpinBox, QPushButton, 
                             QGroupBox, QFormLayout, QMessageBox, QCheckBox,
                             QTabWidget, QTextEdit, QScrollArea, QDialog)
from PyQt5.QtCore import QTimer, Qt
from PyQt5.QtGui import QFont

class CPUSchedulerGUI(QMainWindow):
    def __init__(self):
        super().__init__()
        self.config_file = "/etc/cpu-scheduler.conf"
        self.service_name = "cpu-scheduler.service"
        # 使用硬编码版本号
        self.version = "1.2.38"
        self.init_ui()
        self.load_config()
        self.check_service_status()
    
    def get_package_version(self):
        """获取硬编码版本号"""
        return "1.2.38"
    
    def init_ui(self):
        # 修改窗口标题包含版本信息
        self.setWindowTitle(f"CPU频率调度器 v{self.version}")
        self.setGeometry(100, 100, 600, 600)
        
        # 居中显示窗口
        self.center_window()
        
        # 创建标签页
        tab_widget = QTabWidget()
        self.setCentralWidget(tab_widget)
        
        # 主控制页面
        main_widget = QWidget()
        main_layout = QVBoxLayout(main_widget)
        
        # 服务状态区域
        status_group = QGroupBox("服务状态")
        status_layout = QHBoxLayout()
        self.status_label = QLabel("未知")
        self.status_label.setStyleSheet("QLabel { color : gray; font-weight: bold; }")
        self.toggle_button = QPushButton("启动服务")
        self.toggle_button.clicked.connect(self.toggle_service)
        # 新增恢复CPU最大频率按钮
        self.reset_freq_button = QPushButton("恢复CPU最大频率")
        self.reset_freq_button.clicked.connect(self.reset_cpu_frequency)
        status_layout.addWidget(QLabel("状态:"))
        status_layout.addWidget(self.status_label)
        status_layout.addWidget(self.toggle_button)
        status_layout.addWidget(self.reset_freq_button)
        status_layout.addStretch()
        status_group.setLayout(status_layout)
        main_layout.addWidget(status_group)
        
        # 添加控制开关
        control_group = QGroupBox("控制选项")
        control_layout = QHBoxLayout()  # 修改为水平布局
        
        self.temp_control_checkbox = QCheckBox("启用温度控制")
        self.temp_control_checkbox.setChecked(True)
        self.temp_control_checkbox.stateChanged.connect(self.on_temp_control_changed)
        control_layout.addWidget(self.temp_control_checkbox)
        
        self.freq_control_checkbox = QCheckBox("启用频率控制")
        self.freq_control_checkbox.setChecked(True)
        self.freq_control_checkbox.stateChanged.connect(self.on_freq_control_changed)
        control_layout.addWidget(self.freq_control_checkbox)
        
        control_layout.addStretch()  # 添加弹性空间
        control_group.setLayout(control_layout)
        main_layout.addWidget(control_group)
        
        # 当前频率显示区域
        freq_group = QGroupBox("当前状态")
        freq_layout = QHBoxLayout()
        self.current_freq_label = QLabel("当前频率: --%")
        self.current_temp_label = QLabel("当前温度: --°C")
        # 添加当前CPU最大频率百分比显示
        self.current_max_freq_label = QLabel("最大频率: --%")
        freq_layout.addWidget(self.current_freq_label)
        freq_layout.addWidget(self.current_temp_label)
        freq_layout.addWidget(self.current_max_freq_label)
        freq_group.setLayout(freq_layout)
        main_layout.addWidget(freq_group)
        
        # 配置区域
        config_layout = QFormLayout()
        
        # 检查间隔
        self.interval_spin = QSpinBox()
        self.interval_spin.setRange(1, 300)
        self.interval_spin.setValue(10)
        config_layout.addRow("检查间隔(秒):", self.interval_spin)
        
        # 高频率阈值
        self.high_freq_spin = QSpinBox()
        self.high_freq_spin.setRange(10, 100)
        self.high_freq_spin.setValue(80)
        self.high_freq_spin.setSuffix("%")
        config_layout.addRow("高频率阈值:", self.high_freq_spin)
        
        # 低频率阈值
        self.low_freq_spin = QSpinBox()
        self.low_freq_spin.setRange(10, 100)
        self.low_freq_spin.setValue(40)
        self.low_freq_spin.setSuffix("%")
        config_layout.addRow("低频率阈值:", self.low_freq_spin)
        
        # 高温度阈值
        self.high_temp_spin = QSpinBox()
        self.high_temp_spin.setRange(50, 100)
        self.high_temp_spin.setValue(60)
        self.high_temp_spin.setSuffix("°C")
        config_layout.addRow("高温度阈值:", self.high_temp_spin)
        
        # 低温度阈值
        self.low_temp_spin = QSpinBox()
        self.low_temp_spin.setRange(30, 80)
        self.low_temp_spin.setValue(40)
        self.low_temp_spin.setSuffix("°C")
        config_layout.addRow("低温度阈值:", self.low_temp_spin)
        
        # 持续时间
        self.sustained_spin = QSpinBox()
        self.sustained_spin.setRange(10, 600)
        self.sustained_spin.setValue(60)
        config_layout.addRow("持续时间阈值(秒):", self.sustained_spin)
        
        # 频率调整幅度
        adjustment_layout = QHBoxLayout()
        self.reduction_spin = QSpinBox()
        self.reduction_spin.setRange(5, 50)
        self.reduction_spin.setValue(25)  # 修改为25%
        self.reduction_spin.setSingleStep(5)  # 设置步长为5
        self.reduction_spin.setSuffix("%")
        adjustment_layout.addWidget(self.reduction_spin)
        
        self.increase_spin = QSpinBox()
        self.increase_spin.setRange(5, 50)
        self.increase_spin.setValue(25)  # 修改为25%
        self.increase_spin.setSingleStep(5)  # 设置步长为5
        self.increase_spin.setSuffix("%")
        adjustment_layout.addWidget(self.increase_spin)
        config_layout.addRow("频率调整幅度(降/升):", adjustment_layout)
        
        # 添加最低频率限制配置项
        self.min_freq_limit_spin = QSpinBox()
        # 修改范围为50-95，步长为5
        self.min_freq_limit_spin.setRange(50, 95)
        self.min_freq_limit_spin.setValue(50)  # 修改默认值为50%，与后端一致
        self.min_freq_limit_spin.setSingleStep(5)  # 设置步长为5
        self.min_freq_limit_spin.setSuffix("%")
        config_layout.addRow("最低频率限制:", self.min_freq_limit_spin)
        
        config_group = QGroupBox("配置参数")
        config_group.setLayout(config_layout)
        main_layout.addWidget(config_group)
        
        # 操作按钮
        button_layout = QHBoxLayout()
        self.apply_button = QPushButton("应用配置")
        self.apply_button.clicked.connect(self.apply_config)
        self.reset_button = QPushButton("恢复默认")
        self.reset_button.clicked.connect(self.reset_config)
        self.save_button = QPushButton("保存配置")
        self.save_button.clicked.connect(self.save_config)
        
        # 修改按钮功能说明，明确提及重置CPU频率为100%
        button_help = QLabel("说明: 应用配置(重启服务) | 恢复默认(重置参数为默认并重启服务应用配置) | 保存配置(仅保存)")
        button_help.setStyleSheet("QLabel { color : gray; font-size : 10pt; }")
        
        button_layout.addWidget(self.apply_button)
        button_layout.addWidget(self.reset_button)
        button_layout.addWidget(self.save_button)
        main_layout.addLayout(button_layout)
        main_layout.addWidget(button_help)
        
        # 添加到标签页
        tab_widget.addTab(main_widget, "主控制")
        
        # 添加日志页面
        self.create_log_tab(tab_widget)
        
        # 连接标签页切换信号
        tab_widget.currentChanged.connect(self.on_tab_changed)
        
        # 添加使用说明页面
        self.create_help_tab(tab_widget)
        
        # 定时检查服务状态
        self.timer = QTimer()
        self.timer.timeout.connect(self.check_service_status)
        self.timer.start(5000)  # 每5秒检查一次
        
        # 定时刷新日志
        self.log_timer = QTimer()
        self.log_timer.timeout.connect(self.refresh_log)
        self.log_timer.start(10000)  # 每10秒刷新一次日志
        
        # 定时刷新当前频率和温度
        self.freq_timer = QTimer()
        self.freq_timer.timeout.connect(self.refresh_current_status)
        self.freq_timer.start(2000)  # 每2秒刷新一次
        
        # 在初始化完成后立即刷新一次状态信息
        self.refresh_current_status()
        
    def on_temp_control_changed(self, state):
        """温度控制复选框状态改变时的处理"""
        # 根据温度控制是否启用，决定是否启用温度相关配置
        enabled = state == Qt.Checked
        self.high_temp_spin.setEnabled(enabled)
        self.low_temp_spin.setEnabled(enabled)
        
        # 只有在初始化完成后才自动保存配置并重启服务
        if hasattr(self, '_initialization_complete') and self._initialization_complete:
            self.auto_save_and_restart()
        
    def on_freq_control_changed(self, state):
        """频率控制复选框状态改变时的处理"""
        # 根据频率控制是否启用，决定是否启用频率相关配置
        enabled = state == Qt.Checked
        self.high_freq_spin.setEnabled(enabled)
        self.low_freq_spin.setEnabled(enabled)
        
        # 只有在初始化完成后才自动保存配置并重启服务
        if hasattr(self, '_initialization_complete') and self._initialization_complete:
            self.auto_save_and_restart()
        
    def auto_save_and_restart(self):
        """自动保存配置并重启服务"""
        try:
            # 保存配置到临时文件
            temp_file = self.save_config_to_temp()
            
            # 使用pkexec先保存配置文件
            result1 = subprocess.run(['pkexec', 'cp', temp_file, self.config_file], 
                                    capture_output=True, text=True)
            
            if result1.returncode == 0:
                # 检查是否两个控制选项都禁用
                if not self.temp_control_checkbox.isChecked() and not self.freq_control_checkbox.isChecked():
                    # 如果都禁用，停止服务
                    result = subprocess.run(["pkexec", "systemctl", "stop", self.service_name], 
                                          capture_output=True, text=True)
                    if result.returncode == 0:
                        self.show_detailed_message("信息", "两个控制选项都已禁用，服务已停止")
                        self.check_service_status()
                    else:
                        error_msg = result.stderr if result.stderr else "未知错误"
                        self.show_detailed_message("错误", "停止服务失败", error_msg, QMessageBox.Critical)
                else:
                    # 重启服务以应用新配置，使用pkexec提权
                    # 先停止服务
                    subprocess.run(["pkexec", "systemctl", "stop", self.service_name], 
                                  capture_output=True, text=True)
                    
                    # 然后启动服务（服务启动时会重新加载配置）
                    result2 = subprocess.run(["pkexec", "systemctl", "start", self.service_name], 
                                            capture_output=True, text=True)
                    if result2.returncode == 0:
                        self.check_service_status()
                    else:
                        error_msg = result2.stderr if result2.stderr else "未知错误"
                        self.show_detailed_message("错误", "服务重启失败", error_msg, QMessageBox.Critical)
            else:
                error_msg = result1.stderr if result1.stderr else "未知错误"
                self.show_detailed_message("错误", "保存配置文件失败", error_msg, QMessageBox.Critical)
            
            os.unlink(temp_file)  # 删除临时文件
        except Exception as e:
            self.show_detailed_message("错误", "自动保存和重启时出错", str(e), QMessageBox.Critical)
            
    def show_detailed_message(self, title, message, detailed_text="", icon=QMessageBox.Information):
        """显示可复制文本的详细信息对话框"""
        # 创建对话框
        dialog = QDialog(self)
        dialog.setWindowTitle(title)
        dialog.resize(500, 300)
        
        # 创建布局
        layout = QVBoxLayout(dialog)
        
        # 添加图标和消息
        message_layout = QHBoxLayout()
        if icon == QMessageBox.Information:
            icon_label = QLabel("ℹ️")
        elif icon == QMessageBox.Warning:
            icon_label = QLabel("⚠️")
        elif icon == QMessageBox.Critical:
            icon_label = QLabel("❌")
        elif icon == QMessageBox.Question:
            icon_label = QLabel("❓")
        else:
            icon_label = QLabel("ℹ️")
        
        icon_label.setStyleSheet("QLabel { font-size: 24px; }")
        message_layout.addWidget(icon_label)
        
        message_label = QLabel(message)
        message_label.setWordWrap(True)
        message_layout.addWidget(message_label)
        message_layout.addStretch()
        
        layout.addLayout(message_layout)
        
        # 如果有详细文本，添加文本框
        if detailed_text:
            detail_label = QLabel("详细信息:")
            layout.addWidget(detail_label)
            
            text_edit = QTextEdit()
            text_edit.setPlainText(detailed_text)
            text_edit.setReadOnly(True)
            # 启用文本选择和复制
            text_edit.setTextInteractionFlags(Qt.TextSelectableByMouse | Qt.TextSelectableByKeyboard)
            text_edit.setContextMenuPolicy(Qt.DefaultContextMenu)
            text_edit.setMinimumHeight(150)
            layout.addWidget(text_edit)
        
        # 添加按钮
        button_layout = QHBoxLayout()
        button_layout.addStretch()
        ok_button = QPushButton("确定")
        ok_button.clicked.connect(dialog.accept)
        button_layout.addWidget(ok_button)
        layout.addLayout(button_layout)
        
        dialog.exec_()
        
    def show_question_dialog(self, title, message):
        """显示可复制的问题对话框"""
        # 创建对话框
        dialog = QDialog(self)
        dialog.setWindowTitle(title)
        dialog.resize(400, 150)
        
        # 创建布局
        layout = QVBoxLayout(dialog)
        
        # 添加消息
        message_layout = QHBoxLayout()
        icon_label = QLabel("❓")
        icon_label.setStyleSheet("QLabel { font-size: 24px; }")
        message_layout.addWidget(icon_label)
        
        message_label = QLabel(message)
        message_label.setWordWrap(True)
        message_layout.addWidget(message_label)
        message_layout.addStretch()
        
        layout.addLayout(message_layout)
        
        # 添加按钮
        button_layout = QHBoxLayout()
        button_layout.addStretch()
        yes_button = QPushButton("是")
        no_button = QPushButton("否")
        
        yes_button.clicked.connect(dialog.accept)
        no_button.clicked.connect(dialog.reject)
        
        button_layout.addWidget(yes_button)
        button_layout.addWidget(no_button)
        layout.addLayout(button_layout)
        
        return dialog.exec_() == QDialog.Accepted

    def load_config(self):
        """加载配置文件"""
        if os.path.exists(self.config_file):
            try:
                config = configparser.ConfigParser()
                config.read(self.config_file)
                
                # 如果配置文件没有节标题，尝试修复
                if not config.sections() and not config.defaults():
                    # 读取文件内容并添加节标题
                    with open(self.config_file, 'r') as f:
                        content = f.read()
                    with open(self.config_file, 'w') as f:
                        f.write('[DEFAULT]\n' + content)
                    # 重新读取
                    config.read(self.config_file)
                
                if 'DEFAULT' in config or config.defaults():
                    cfg = config['DEFAULT'] if 'DEFAULT' in config else config.defaults()
                    self.interval_spin.setValue(int(cfg.get('CHECK_INTERVAL', 10)))
                    self.high_freq_spin.setValue(int(cfg.get('HIGH_FREQ_THRESHOLD', 80)))
                    self.low_freq_spin.setValue(int(cfg.get('LOW_FREQ_THRESHOLD', 40)))
                    self.high_temp_spin.setValue(int(cfg.get('HIGH_TEMP_THRESHOLD', 60)))
                    self.low_temp_spin.setValue(int(cfg.get('LOW_TEMP_THRESHOLD', 40)))
                    self.sustained_spin.setValue(int(cfg.get('SUSTAINED_PERIOD', 60)))
                    self.reduction_spin.setValue(int(cfg.get('FREQ_REDUCTION', 25)))  # 修改为25%
                    self.increase_spin.setValue(int(cfg.get('FREQ_INCREASE', 25)))    # 修改为25%
                    # 加载新配置项
                    temp_control_enabled = cfg.getboolean('ENABLE_TEMP_CONTROL', True)
                    freq_control_enabled = cfg.getboolean('ENABLE_FREQ_CONTROL', True)
                    self.temp_control_checkbox.setChecked(temp_control_enabled)
                    self.freq_control_checkbox.setChecked(freq_control_enabled)
                    # 加载最低频率限制配置项
                    min_freq_value = int(cfg.get('MIN_FREQ_LIMIT', 50))  # 默认值改为75，与后端一致
                    # 确保最低频率限制不低于50%
                    if min_freq_value < 50:
                        min_freq_value = 50
                    self.min_freq_limit_spin.setValue(min_freq_value)
            except Exception as e:
                self.show_detailed_message("警告", "加载配置文件时出错", str(e), QMessageBox.Warning)
                
        # 标记初始化完成
        self._initialization_complete = True
    
    def save_config_to_temp(self):
        """保存配置到临时文件并返回文件路径"""
        # 检查最低频率限制是否低于50%
        if self.min_freq_limit_spin.value() < 50:
            self.show_detailed_message("错误", "最低频率限制不能低于50%，该设置会影响性能体验", 
                                     "最低频率限制已自动调整为50%", QMessageBox.Warning)
            self.min_freq_limit_spin.setValue(50)
        
        config = configparser.ConfigParser()
        config['DEFAULT'] = {
            'CHECK_INTERVAL': str(self.interval_spin.value()),
            'HIGH_FREQ_THRESHOLD': str(self.high_freq_spin.value()),
            'LOW_FREQ_THRESHOLD': str(self.low_freq_spin.value()),
            'HIGH_TEMP_THRESHOLD': str(self.high_temp_spin.value()),
            'LOW_TEMP_THRESHOLD': str(self.low_temp_spin.value()),
            'SUSTAINED_PERIOD': str(self.sustained_spin.value()),
            'FREQ_REDUCTION': str(self.reduction_spin.value()),
            'FREQ_INCREASE': str(self.increase_spin.value()),
            'LOG_FILE': '/var/log/cpu-scheduler.log',
            'ENABLE_TEMP_CONTROL': str(self.temp_control_checkbox.isChecked()).lower(),
            'ENABLE_FREQ_CONTROL': str(self.freq_control_checkbox.isChecked()).lower(),
            'MIN_FREQ_LIMIT': str(self.min_freq_limit_spin.value()),  # 保存最低频率限制配置
        }
        
        temp_file = tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.conf')
        config.write(temp_file)
        temp_file.close()
        return temp_file.name
    
    def save_config(self):
        """保存配置到文件（需要权限）"""
        # 检查最低频率限制是否低于50%
        if self.min_freq_limit_spin.value() < 50:
            self.show_detailed_message("错误", "最低频率限制不能低于50%，该设置会影响性能体验", 
                                     "最低频率限制已自动调整为50%", QMessageBox.Warning)
            self.min_freq_limit_spin.setValue(50)
        
        try:
            # 保存配置到临时文件
            temp_file = self.save_config_to_temp()
            
            # 使用pkexec复制文件到目标位置
            result = subprocess.run(['pkexec', 'cp', temp_file, self.config_file], 
                                  capture_output=True, text=True)
            os.unlink(temp_file)  # 删除临时文件
            
            if result.returncode == 0:
                self.show_detailed_message("成功", "配置已保存到 /etc/cpu-scheduler.conf")
            else:
                error_msg = result.stderr if result.stderr else "未知错误"
                self.show_detailed_message("错误", "保存配置文件失败", error_msg, QMessageBox.Critical)
        except Exception as e:
            self.show_detailed_message("错误", "保存配置文件时出错", str(e), QMessageBox.Critical)
    
    def check_service_status(self):
        """检查服务状态"""
        try:
            result = subprocess.run(["systemctl", "is-active", self.service_name], 
                                  capture_output=True, text=True)
            if result.stdout.strip() == "active":
                self.status_label.setText("运行中")
                self.status_label.setStyleSheet("QLabel { color : green; font-weight: bold; }")
                self.toggle_button.setText("停止服务")
            else:
                self.status_label.setText("已停止")
                self.status_label.setStyleSheet("QLabel { color : red; font-weight: bold; }")
                self.toggle_button.setText("启动服务")
        except Exception as e:
            self.status_label.setText("未知")
            self.status_label.setStyleSheet("QLabel { color : gray; font-weight: bold; }")
            self.toggle_button.setText("启动服务")
            
    def toggle_service(self):
        """切换服务状态"""
        try:
            current_status = self.status_label.text()
            if current_status == "运行中":
                # 停止服务，使用pkexec提权
                result = subprocess.run(["pkexec", "systemctl", "stop", self.service_name], 
                                      capture_output=True, text=True)
                if result.returncode != 0 and "拒绝" not in result.stderr and "cancelled" not in result.stderr.lower():
                    error_msg = result.stderr if result.stderr else "未知错误"
                    self.show_detailed_message("错误", "停止服务失败", error_msg, QMessageBox.Critical)
            else:
                # 启动服务，使用pkexec提权
                result = subprocess.run(["pkexec", "systemctl", "start", self.service_name], 
                                      capture_output=True, text=True)
                if result.returncode != 0 and "拒绝" not in result.stderr and "cancelled" not in result.stderr.lower():
                    error_msg = result.stderr if result.stderr else "未知错误"
                    self.show_detailed_message("错误", "启动服务失败", error_msg, QMessageBox.Critical)
            
            self.check_service_status()
        except Exception as e:
            self.show_detailed_message("错误", "操作服务时出错", str(e), QMessageBox.Critical)
            
    def apply_config(self):
        """应用配置（重启服务以应用新配置）"""
        # 检查最低频率限制是否低于50%
        if self.min_freq_limit_spin.value() < 50:
            self.show_detailed_message("错误", "最低频率限制不能低于50%，该设置会影响性能体验", 
                                     "最低频率限制已自动调整为50%", QMessageBox.Warning)
            self.min_freq_limit_spin.setValue(50)
        
        reply = self.show_question_dialog('确认', '应用配置需要重启服务，是否继续？')
        if reply:
            try:
                # 保存配置到临时文件
                temp_file = self.save_config_to_temp()
                
                # 使用pkexec先保存配置文件
                result1 = subprocess.run(['pkexec', 'cp', temp_file, self.config_file], 
                                    capture_output=True, text=True)
                
                if result1.returncode == 0:
                    # 重启服务以应用新配置，使用pkexec提权
                    # 先停止服务
                    subprocess.run(["pkexec", "systemctl", "stop", self.service_name], 
                                capture_output=True, text=True)
                    
                    # 然后启动服务（服务启动时会重新加载配置）
                    result2 = subprocess.run(["pkexec", "systemctl", "start", self.service_name], 
                                        capture_output=True, text=True)
                    if result2.returncode == 0:
                        self.show_detailed_message("成功", "配置已应用，服务已重启")
                        self.check_service_status()
                    else:
                        error_msg = result2.stderr if result2.stderr else "未知错误"
                        self.show_detailed_message("错误", "配置应用失败", error_msg, QMessageBox.Critical)
                else:
                    error_msg = result1.stderr if result1.stderr else "未知错误"
                    self.show_detailed_message("错误", "保存配置文件失败", error_msg, QMessageBox.Critical)
                
                os.unlink(temp_file)  # 删除临时文件
            except Exception as e:
                self.show_detailed_message("错误", "应用配置时出错", str(e), QMessageBox.Critical)
    
    def reset_config(self):
        """重置为默认配置"""
        reply = self.show_question_dialog('确认', '是否重置所有配置为默认值，并重启服务应用默认配置？')
        if reply:
            # 重置为默认值
            self.interval_spin.setValue(10)
            self.high_freq_spin.setValue(80)
            self.low_freq_spin.setValue(40)
            self.high_temp_spin.setValue(60)
            self.low_temp_spin.setValue(40)
            self.sustained_spin.setValue(60)
            self.reduction_spin.setValue(25)  # 修改为25%
            self.increase_spin.setValue(25)   # 修改为25%
            # 重置控制开关
            self.temp_control_checkbox.setChecked(True)
            self.freq_control_checkbox.setChecked(True)
            # 添加重置最低频率限制为默认值
            self.min_freq_limit_spin.setValue(50)
            
            # 更新相关配置项的启用状态
            self.on_temp_control_changed(Qt.Checked)
            self.on_freq_control_changed(Qt.Checked)
            
            # 保存配置并重启服务
            try:
                # 保存配置到临时文件
                temp_file = self.save_config_to_temp()
                
                # 使用pkexec先保存配置文件
                result1 = subprocess.run(['pkexec', 'cp', temp_file, self.config_file], 
                                    capture_output=True, text=True)
                
                if result1.returncode == 0:
                    # 重启服务以应用新配置，使用pkexec提权
                    # 先停止服务
                    subprocess.run(["pkexec", "systemctl", "stop", self.service_name], 
                                capture_output=True, text=True)
                    
                    # 然后启动服务（服务启动时会重新加载配置）
                    result2 = subprocess.run(["pkexec", "systemctl", "start", self.service_name], 
                                        capture_output=True, text=True)
                    if result2.returncode == 0:
                        self.show_detailed_message("成功", "配置已重置，服务已重启")
                        self.check_service_status()
                    else:
                        error_msg = result2.stderr if result2.stderr else "未知错误"
                        self.show_detailed_message("错误", "服务重启失败", error_msg, QMessageBox.Critical)
                else:
                    error_msg = result1.stderr if result1.stderr else "未知错误"
                    self.show_detailed_message("错误", "保存配置文件失败", error_msg, QMessageBox.Critical)
                
                os.unlink(temp_file)  # 删除临时文件
            except Exception as e:
                self.show_detailed_message("错误", "重置配置时出错", str(e), QMessageBox.Critical)
    
    def reset_cpu_frequency(self):
        """恢复CPU最大频率"""
        reply = self.show_question_dialog('确认', '是否将CPU频率恢复到硬件支持的最大频率？')
        if reply:
            try:
                # 使用pkexec执行cpu_scheduler.py的--reset-freq选项来恢复CPU频率
                result = subprocess.run(["pkexec", "/usr/local/bin/cpu_scheduler.py", "--reset-freq"], 
                                       capture_output=True, text=True)
                if result.returncode == 0:
                    self.show_detailed_message("成功", "CPU频率已恢复到硬件支持的最大频率")
                else:
                    error_msg = result.stderr if result.stderr else "未知错误"
                    self.show_detailed_message("错误", "恢复CPU频率失败", error_msg, QMessageBox.Critical)
            except Exception as e:
                self.show_detailed_message("错误", "恢复CPU频率时出错", str(e), QMessageBox.Critical)

    def clear_log(self):
        """清空日志显示"""
        self.log_text.clear()
        
    def refresh_log(self):
        """刷新日志显示"""
        try:
            if os.path.exists("/var/log/cpu-scheduler.log"):
                with open("/var/log/cpu-scheduler.log", "r") as f:
                    lines = f.readlines()
                    # 只显示最后100行
                    last_lines = lines[-100:] if len(lines) > 100 else lines
                    self.log_text.setPlainText("".join(last_lines))
                    # 滚动到底部
                    self.log_text.verticalScrollBar().setValue(self.log_text.verticalScrollBar().maximum())
        except Exception as e:
            pass

    def create_log_tab(self, tab_widget):
        """创建日志页面"""
        log_widget = QWidget()
        log_layout = QVBoxLayout(log_widget)
        
        # 日志显示区域
        log_group = QGroupBox("服务日志")
        log_layout_inner = QVBoxLayout()
        self.log_text = QTextEdit()
        self.log_text.setReadOnly(True)
        # 启用文本选择和复制功能
        self.log_text.setTextInteractionFlags(Qt.TextSelectableByMouse | Qt.TextSelectableByKeyboard)
        self.log_text.setContextMenuPolicy(Qt.DefaultContextMenu)  # 启用右键菜单
        self.log_text.setLineWrapMode(QTextEdit.NoWrap)  # 可选：禁用自动换行以便于复制
        log_layout_inner.addWidget(self.log_text)

        
        log_button_layout = QHBoxLayout()
        self.clear_log_button = QPushButton("清空日志")
        self.clear_log_button.clicked.connect(self.clear_log)
        self.refresh_log_button = QPushButton("刷新日志")
        self.refresh_log_button.clicked.connect(self.refresh_log)
        log_button_layout.addWidget(self.clear_log_button)
        log_button_layout.addWidget(self.refresh_log_button)
        log_layout_inner.addLayout(log_button_layout)
        
        log_group.setLayout(log_layout_inner)
        log_layout.addWidget(log_group)
        
        # 添加到标签页
        tab_widget.addTab(log_widget, "日志")
    
    def create_help_tab(self, tab_widget):
        """创建使用说明页面"""
        help_widget = QWidget()
        help_layout = QVBoxLayout(help_widget)
        
        # 创建滚动区域以容纳长内容
        scroll_area = QScrollArea()
        scroll_area.setWidgetResizable(True)
        help_layout.addWidget(scroll_area)
        
        # 创建内容区域
        content_widget = QWidget()
        content_layout = QVBoxLayout(content_widget)
        
        # 添加标题
        title_label = QLabel("CPU频率调度器使用说明")
        title_font = QFont()
        title_font.setPointSize(16)
        title_font.setBold(True)
        title_label.setFont(title_font)
        title_label.setAlignment(Qt.AlignCenter)
        content_layout.addWidget(title_label)
        
        # 从Markdown文件加载帮助内容
        help_text = QTextEdit()
        help_text.setReadOnly(True)
        
        # 尝试加载Markdown文档
        help_md_path = "/usr/share/cpu-scheduler-pro/help.md"
        if not os.path.exists(help_md_path):
            help_md_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "help.md")
            
        if os.path.exists(help_md_path):
            try:
                with open(help_md_path, 'r', encoding='utf-8') as f:
                    markdown_content = f.read()
                    # 简单的Markdown到HTML转换
                    html_content = self.markdown_to_html(markdown_content)
                    help_text.setHtml(html_content)
            except Exception as e:
                help_text.setHtml(f"<p>无法加载帮助文档: {str(e)}</p>")
        else:
            # 如果找不到Markdown文件，显示默认内容
            help_text.setHtml("""
            <p>帮助文档未找到。</p>
            <p>请确保 /usr/share/cpu-scheduler-pro/help.md 文件存在。</p>
            """)
        
        content_layout.addWidget(help_text)
        
        # 设置滚动区域内容
        scroll_area.setWidget(content_widget)
        
        # 添加到标签页
        tab_widget.addTab(help_widget, "使用说明")
    
    def markdown_to_html(self, markdown_text):
        """简单的Markdown到HTML转换"""
        import re
        
        # 转换标题并加粗
        markdown_text = re.sub(r'^(#+)\s+(.*)$', r'<h\1><b>\2</b></h\1>', markdown_text, flags=re.MULTILINE)
        markdown_text = markdown_text.replace('<h1>', '<h3>').replace('</h1>', '</h3>')
        markdown_text = markdown_text.replace('<h2>', '<h4>').replace('</h2>', '</h4>')
        
        # 转换粗体
        markdown_text = re.sub(r'\*\*(.*?)\*\*', r'<b>\1</b>', markdown_text)
        
        # 转换斜体
        markdown_text = re.sub(r'\*(.*?)\*', r'<i>\1</i>', markdown_text)
        
        # 转换链接 [text](url) - 修正链接转换逻辑，避免重复处理
        markdown_text = re.sub(r'\[([^\]]+)\]\(([^)]+)\)', r'<a href="\2">\1</a>', markdown_text)
        
        # 转换裸链接 http:// 或 https:// (仅处理未被Markdown格式包含的链接)
        # 使用负向先行断言避免处理已经转换的Markdown链接
        markdown_text = re.sub(r'(?<!href=")https?://[^\s<>"\']+', r'<a href="\g<0>">\g<0></a>', markdown_text)
        
        # 转换列表
        lines = markdown_text.split('\n')
        in_list = False
        html_lines = []
        
        for line in lines:
            if line.strip().startswith('- '):
                if not in_list:
                    html_lines.append('<ul>')
                    in_list = True
                html_lines.append('<li>' + line[2:] + '</li>')
            else:
                if in_list:
                    html_lines.append('</ul>')
                    in_list = False
                html_lines.append(line)
        
        if in_list:
            html_lines.append('</ul>')
            
        markdown_text = '\n'.join(html_lines)
        
        # 转换段落
        paragraphs = markdown_text.split('\n\n')
        html_paragraphs = []
        for p in paragraphs:
            if not p.startswith('<'):
                html_paragraphs.append('<p>' + p + '</p>')
            else:
                html_paragraphs.append(p)
                
        return '\n'.join(html_paragraphs)
    
    def on_tab_changed(self, index):
        """标签页切换时的处理函数"""
        # 获取当前标签页的文本
        tab_widget = self.centralWidget()
        current_tab_text = tab_widget.tabText(index)
        
        # 如果切换到日志页面，自动刷新日志
        if current_tab_text == "日志":
            self.refresh_log()
    
    def refresh_current_status(self):
        """刷新当前CPU频率和温度显示"""
        try:
            # 获取当前CPU频率
            freq = self.get_cpu_frequency()
            if freq > 0:
                self.current_freq_label.setText(f"当前频率: {freq}%")
            else:
                self.current_freq_label.setText("当前频率: --%")
                
            # 获取当前CPU温度
            temp = self.get_cpu_temperature()
            if temp > 0:
                self.current_temp_label.setText(f"当前温度: {temp}°C")
            else:
                self.current_temp_label.setText("当前温度: --°C")
                
            # 获取当前CPU最大频率百分比
            max_freq_percent = self.get_cpu_max_frequency_percent()
            if max_freq_percent > 0:
                self.current_max_freq_label.setText(f"当前最大频率: {max_freq_percent}%")
            else:
                self.current_max_freq_label.setText("当前最大频率: --%")
        except Exception as e:
            self.current_freq_label.setText("当前频率: 错误")
            self.current_temp_label.setText("当前温度: 错误")
            self.current_max_freq_label.setText("当前最大频率: 错误")
    
    def get_cpu_frequency(self):
        """获取当前CPU频率（百分比）"""
        total_freq = 0
        cpu_count = 0
        
        cpu_dirs = glob.glob("/sys/devices/system/cpu/cpu[0-9]*")
        for cpu_dir in cpu_dirs:
            cpufreq_path = os.path.join(cpu_dir, "cpufreq")
            if os.path.exists(cpufreq_path):
                try:
                    with open(os.path.join(cpufreq_path, "scaling_cur_freq"), 'r') as f:
                        current_freq = int(f.read().strip())
                    with open(os.path.join(cpufreq_path, "cpuinfo_max_freq"), 'r') as f:
                        hw_max_freq = int(f.read().strip())
                    
                    if hw_max_freq != 0:
                        core_percent = int((current_freq * 100) / hw_max_freq)
                        total_freq += core_percent
                        cpu_count += 1
                except Exception:
                    continue
        
        if cpu_count > 0:
            avg_freq = total_freq // cpu_count
            return avg_freq
        else:
            return 0
    
    def get_cpu_max_frequency_percent(self):
        """获取当前CPU最大频率设置（百分比）"""
        try:
            cpu_dir = "/sys/devices/system/cpu/cpu0/cpufreq"
            if os.path.exists(cpu_dir):
                with open(os.path.join(cpu_dir, "scaling_max_freq"), 'r') as f:
                    current_max_freq = int(f.read().strip())
                with open(os.path.join(cpu_dir, "cpuinfo_max_freq"), 'r') as f:
                    hw_max_freq = int(f.read().strip())
                
                if hw_max_freq != 0:
                    max_freq_percent = int((current_max_freq * 100) / hw_max_freq)
                    return max_freq_percent
        except Exception:
            pass
        return 0
    
    def get_cpu_temperature(self):
        """获取CPU温度"""
        # 方法1: 使用sensors命令
        try:
            result = subprocess.run(['sensors'], capture_output=True, text=True, timeout=5)
            if result.returncode == 0:
                for line in result.stdout.split('\n'):
                    if any(keyword in line for keyword in ["Core", "Tctl", "CPU Temp"]):
                        # 提取温度值
                        import re
                        temps = re.findall(r'[0-9]+\.[0-9]+', line)
                        if temps:
                            return int(float(temps[0]))
        except Exception:
            pass
        
        # 方法2: 读取thermal zone
        try:
            thermal_zones = glob.glob("/sys/class/thermal/thermal_zone*")
            for zone in thermal_zones:
                type_path = os.path.join(zone, "type")
                temp_path = os.path.join(zone, "temp")
                
                if os.path.exists(type_path) and os.path.exists(temp_path):
                    with open(type_path, 'r') as f:
                        zone_type = f.read().strip()
                    
                    if "cpu" in zone_type.lower() or "x86_pkg" in zone_type:
                        with open(temp_path, 'r') as f:
                            temp = int(f.read().strip())
                        
                        # 转换为摄氏度
                        if temp > 1000:
                            temp = temp // 1000
                        return temp
        except Exception:
            pass
        
        return 0
    
    def center_window(self):
        """将窗口居中显示在屏幕中央"""
        # 获取屏幕尺寸
        screen = QApplication.primaryScreen()
        screen_geometry = screen.availableGeometry()
        
        # 计算窗口居中位置
        window_width = self.width()
        window_height = self.height()
        x = (screen_geometry.width() - window_width) // 2
        y = (screen_geometry.height() - window_height) // 2
        
        # 移动窗口到居中位置
        self.move(x, y)

def main():
    app = QApplication(sys.argv)
    window = CPUSchedulerGUI()
    window.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()